using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.Reflection;

using Dashboard.Util;

namespace Dashboard
{
	public delegate void MessageHandler (Message message);

	public class Message : Identifiable, ICloneable
	{
		private static XmlSerializer serializer;
		private static object serializer_lock = new object ();
		
		private static Type[] message_types;
                private static object type_lock = new object ();

		protected string path = null;
		
		public Message ()
		{

		}
		
		public Message (string path)
		{
			this.path = path;
		}

		public object Clone ()
		{
			return MemberwiseClone ();
		}

		public override string ToString ()
		{
			StringWriter writer = new StringWriter ();
			Serializer.Serialize (writer, this);
			writer.Close ();
			return writer.ToString ();
		}

		[XmlAttribute]
		public string Path {
			get { return path; }
			set { path = value; }
		}

		[XmlIgnore]
		public static XmlSerializer Serializer
		{
			get {
				lock (serializer_lock) {
					if (serializer == null)
						serializer = new XmlSerializer (typeof (Message), Message.Types);
				}

				return serializer;
			}
		}

		[XmlIgnore]
		public static Type[] Types {
                        get {
                                lock (type_lock) {
                                        if (message_types == null) {
						List<Type> types = new List<Type> ();
						
						foreach (Assembly ass in AppDomain.CurrentDomain.GetAssemblies ())
							types.AddRange (ReflectionFu.ScanAssemblyForClass (ass, typeof(Message)));
						
                                                message_types = (Type[]) types.ToArray ();
					}
                                }
				
                                return message_types;
                        }
                }
	}
}